const ffmpeg = require('fluent-ffmpeg');
const fs = require('fs');
const path = require('path');
const os = require('os');

const inputPath = process.argv[2];
if (!inputPath || !fs.existsSync(inputPath)) {
    console.error("请提供有效的视频文件路径");
    process.exit(1);
}

const videoName = path.basename(inputPath, path.extname(inputPath));
const outputDir = path.join(__dirname, 'output', videoName);
fs.mkdirSync(outputDir, { recursive: true });

console.log('开始提取视频帧(强化去重模式)...');
console.time('帧提取耗时');

const cpuCores = os.cpus().length;
const threadCount = Math.max(2, cpuCores - 1); 
const outputPattern = path.join(outputDir, 'frame_%05d.jpg');

let totalFrames = 0;
let outputFrames = 0;

// 使用ffprobe获取视频信息
ffmpeg.ffprobe(inputPath, (err, metadata) => {
    if (!err && metadata.streams && metadata.streams.length > 0) {
        const videoStream = metadata.streams.find(s => s.codec_type === 'video');
        if (videoStream) {
            totalFrames = parseInt(videoStream.nb_frames);
            if (isNaN(totalFrames) || totalFrames <= 0) {
                const duration = parseFloat(videoStream.duration || 0);
                const fps = videoStream.avg_frame_rate_split = videoStream.avg_frame_rate.split('/');
                const fpsVal = fps.length === 2 
                    ? parseFloat(fps[0]) / parseFloat(fps[1])
                    : parseFloat(videoStream.avg_frame_rate);
                
                if (!isNaN(duration) && !isNaN(fpsVal) && duration > 0 && fpsVal > 0) {
                    totalFrames = Math.ceil(duration * fpsVal);
                }
            }
            console.log(`原始视频帧数: ${totalFrames}`);
        }
    }
    
    if (totalFrames <= 0) {
        console.warn('⚠️ 无法获取总帧数，进度显示可能不准确');
    }

    // 主处理流程
    const command = ffmpeg(inputPath)
        .output(outputPattern)
        .complexFilter([
            // 关键修改：强化去重参数
            '[0:v]mpdecimate=hi=64:lo=32:frac=0.3,scale=1920:-1[out]'
        ])
        .outputOptions([
            '-map', '[out]',
            '-q:v', '2',
            `-threads`, `${threadCount}`,
            '-vsync', 'vfr'
        ])
        .on('start', cmd => console.log(`执行命令: ${cmd}`))
        .on('error', err => {
            console.error('处理视频时出现错误:', err.message);
        })
        .on('end', () => {
            // 精确统计输出帧数
            fs.readdir(outputDir, (err, files) => {
                if (err) {
                    console.error('读取输出目录时出错:', err);
                } else {
                    const jpgFiles = files.filter(file => file.endsWith('.jpg'));
                    outputFrames = jpgFiles.length;
                    const reduction = totalFrames > 0 
                        ? `(去重率: ${((1 - outputFrames/totalFrames)*100).toFixed(1)}%)` 
                        : '';
                    
                    console.log([
                        '='.repeat(50),
                        `处理完成! 耗时: ${console.timeEnd('帧提取耗时')}`,
                        `原始帧数: ${totalFrames || 'N/A'}`,
                        `输出去重帧: ${outputFrames} ${reduction}`,
                        '='.repeat(50)
                    ].join('\n'));
                }
            });
        })
        .on('progress', progress => {
            const frame = progress.frames || 0;
            if (totalFrames > 0) {
                const percent = (frame / totalFrames * 100).toFixed(1);
                console.log(`处理中... 已提取帧: ${frame}/${totalFrames} (${percent}%)`);
            } else {
                console.log(`处理中... 当前帧: ${frame}`);
            }
        });
    
    command.run();
});











// const ffmpeg = require('fluent-ffmpeg');
// const fs = require('fs');
// const path = require('path');
// const os = require('os');

// const inputPath = process.argv[2];
// if (!inputPath || !fs.existsSync(inputPath)) {
//     console.error("请提供有效的视频文件路径");
//     process.exit(1);
// }

// const videoName = path.basename(inputPath, path.extname(inputPath));
// const outputDir = path.join(__dirname, 'output', videoName);
// fs.mkdirSync(outputDir, { recursive: true });

// console.log('开始提取视频帧...');
// console.time('帧提取耗时');

// const cpuCores = os.cpus().length;
// const threadCount = Math.max(2, cpuCores - 1); // 留出一个核心给系统
// const outputPattern = path.join(outputDir, 'frame_%05d.jpg');

// // 记录视频总帧数，用于统计
// let totalFrames = 0;

// ffmpeg(inputPath)
//   .output(outputPattern)
//   .complexFilter([
//     // 使用mpdecimate滤镜去除重复帧，并缩放
//     '[0:v]mpdecimate=hi=256:lo=128:frac=0.1,scale=1920:-1[out]'
//   ])
//   .outputOptions([
//     '-map', '[out]',   // 映射过滤后的输出流
//     '-q:v', '2',       // 输出质量
//     `-threads`, `${threadCount}`, // 全局线程数
//     '-vsync', 'vfr'   // 可变帧率
//   ])
//   .on('start', cmd => console.log(`执行命令: ${cmd}`))
//   .on('error', err => {
//     console.error('处理视频时出现错误:', err.message);
//   })
//   .on('end', () => {
//     console.log('帧提取已完成！');
//     console.timeEnd('帧提取耗时');
    
//     // 统计生成的帧数
//     fs.readdir(outputDir, (err, files) => {
//       if (err) {
//         console.error('读取输出目录时出错:', err);
//       } else {
//         const jpgFiles = files.filter(file => file.endsWith('.jpg'));
//         console.log(`提取了 ${jpgFiles.length} 张图像 (去重后)`);
//       }
//     });
//   })
//   .on('codecData', (data) => {
//     // 通过时间乘帧率估算总帧数
//     totalFrames = Math.ceil(parseFloat(data.duration) * parseFloat(data.video_fps));
//     console.log(`原始视频帧数约为: ${totalFrames}`);
//   })
//   .on('progress', progress => {
//     // 由于去重，实际帧数小于总帧数，所以进度百分比可能不准确，但可以显示已处理的帧数
//     console.log(`当前帧: ${progress.frames}，进度: ${totalFrames ? Math.round(progress.frames / totalFrames * 100) : '未知'}%`);
//   })
//   .run();





// const ffmpeg = require('fluent-ffmpeg');
// const fs = require('fs');
// const path = require('path');

// const inputPath = process.argv[2];
// if (!inputPath || !fs.existsSync(inputPath)) {
//     console.error("请提供有效的视频文件路径");
//     process.exit(1);
// }

// const videoName = path.basename(inputPath, path.extname(inputPath));
// const outputDir = path.join(__dirname, 'output', videoName);

// fs.mkdirSync(outputDir, { recursive: true });

// console.log('inputPath: ', inputPath);
// ffmpeg(inputPath)
//   .output(path.join(outputDir, 'frame_%05d.jpg'))
//   .outputOptions([
//     '-qscale:v 2' // 高质量 JPG
//   ])
//   .on('end', () => {
//     console.log(`所有帧已成功提取至：${outputDir}`);
//   })
//   .on('error', (err) => {
//     console.error('提取帧时出错:', err.message);
//   })
//   .run();